﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using System.Runtime;
using System.Runtime.Serialization;
//using DataBase;

namespace Database
{
    [DataContract]
    public class DBmediator : DataBaseImpl
    {
    //    [DataMember]
    //    private DataBase dataBase;
        [DataMember]
        private SQLInit sql_init;
        //+
        public DBmediator(){   
            sql_init = new SQLInit();
            //director
            User admin = sql_init.getDirector();
        //    dataBase = new DataBase(admin);
        //    sql_init.initDataBase(this);
        }

        //+return forums in database
        public SortedDictionary<int, Forum> getForums() {
            return sql_init.getForums();
        }
        
        //+ return director ->מנהל על  
        public User getDirector() {
            return this.sql_init.getDirector();
        }

        //+ return SortedDictionary <int, string> : int -> id, string -> the forums titles
        public SortedDictionary<int, string> dataBasetoString() {
            return sql_init.dataBasetoString();
        }

        //+ return the number of forums in database
        public int getNumOfForums()
        {
            return sql_init.getNumOfForums();
        }
        //set the number of forums in database
  
        /*- public void setIdForForums(int num)
        {
            dataBase.setIdForForums(num);
        } */

        /////////////////////////////   Forums    ////////////////////////////////////////////////////
        //+
        public Forum getForum(int forumId) {
            return sql_init.getForum(forumId);
        }
        //+
        public int getForumType(int forumId) {
            return sql_init.getForumType(forumId);
        }
        //+
        public int addForum(string title, User admin, int type) {
            int id = sql_init.getidforForums() + 1;
            sql_init.addForum(title, id, admin.getUserName(), admin.getName(), admin.getLastName(), admin.getPassword(), admin.getEmail(), type);
            return id;
        }
        //+
        public string getForumTitle(int forumId) {
            return sql_init.getForumTitle(forumId);
        }
        //+
        public void setForumTitle(int forumId, string title){
                sql_init.updateForumTitle(forumId, title);
        }

 /*-      public void setIdForSubForums(int forumId, int numForId){
            if (dataBase.getForums().ContainsKey(forumId))
                dataBase.getForum(forumId).setIdForSubForums(numForId);
        }*/
        //+
        public User getForumAdmin(int forumId) {
            return sql_init.getForumAdmin(forumId);
        }
        //+
        public SortedDictionary<string, User> getForumUsers(int forumId) {
                return sql_init.getForumUsers(forumId);
        }
        //+
        public bool isForumUser(int forumId, string user){
            return sql_init.isForumUser(forumId, user);
        }


        /////////////////////////////         SubForums        ////////////////////////////////////////////////////
        //+
        public SubForum getSubForum(int forumId, int subForumId)
        {
            return sql_init.getSubForum(forumId, subForumId);
        }
        //+
        public int addSubForum(int forumId, string title)
        {
            User admin = sql_init.getForumAdmin(forumId);
            int subForumId = sql_init.getIdForSubForums(forumId) + 1;
                //update database
            sql_init.addSubForum(subForumId, title, forumId, admin.getUserName());
            return subForumId;

        }
        //+
        public bool removeSubForum(int forumId, int subForumId)
        {
            return sql_init.removeSubForum(forumId, subForumId);
        }
        //+
        public void setSubForumTitle(int forumId, int subForumId, string title)
        {
            sql_init.updateSubForumTitle(subForumId, forumId, title);
        }
        //+
        public string getSubForumTitle(int forumId, int subForumId)
        {
            return sql_init.getSubForumTitle(forumId, subForumId);
        }
        //+
        public bool addSubForumModerator(int forumId, int subForumId, string uname)
        {
         return sql_init.addSubForumModerator(forumId, subForumId, uname);     
        }
        //+
        public bool removeSubForumModerator(int forumId, int subForumId, string uname)
        {
            return sql_init.removeSubForumModerator(forumId, subForumId, uname);
        }
        //+
        public SortedDictionary<string, User> getSubForumModerators(int forumId, int subForumId)
        {
            return sql_init.getSubForumModerators(forumId, subForumId);
        }

     /*   public void complaint(int forumId, int subForumId, string uname)
        {
            if (dataBase.getForums().ContainsKey(forumId))
            {
                User moderator = dataBase.getForum(forumId).getRegUser(uname);
                dataBase.getForum(forumId).getSubForum(subForumId).complain(moderator);
            }
        }
     */
        //+
        public SortedDictionary<int, Thread> getSubForumThreads(int forumId, int subForumId)
        {
            return sql_init.getSubForumThreads(forumId, subForumId);
        }

 /*-       public void setIdForThreads(int forumId, int subForumId, int num) {
            if (dataBase.getForums().ContainsKey(forumId))
                dataBase.getForum(forumId).getSubForum(subForumId).setIdForThreads(num);
        }*/


        /////////////////////////////          Thread        ////////////////////////////////////////////////
        //+
        public Thread getThread(int forumId, int subForumId, int threadId) {
            return sql_init.getThread(forumId, subForumId, threadId);
        }

        //+ in success return thread id, otherwise -1
        public int addThread(int forumId, int subForumId, string title, string body, User user)
        {
            int threadId = sql_init.getIdForThreads(forumId, subForumId) + 1;
            sql_init.addThread(threadId, forumId, subForumId, title, body, user.getUserName());
            return threadId;
        }
        //+
        public bool removeThread(int forumId, int subForumId, int threadId)
        {
            return sql_init.removeThread(forumId, subForumId, threadId);
        }
        //+
        public void setThreadTitle(int forumId, int subForumId, int threadId, string title)
        {
            sql_init.updateThreadTitle(forumId, subForumId, threadId, title);  
        }
        //+
        public string getThreadTitle(int forumId, int subForumId, int threadId)
        {
            return sql_init.getThreadTitle(forumId, subForumId, threadId);
        }
        //+
        public void setThreadBody(int forumId, int subForumId, int threadId, string body)
        {
            sql_init.updateThreadBody(forumId, subForumId, threadId, body); 
        }
        //+
        public string getThreadBody(int forumId, int subForumId, int threadId)
        {
            return sql_init.getThreadBody(forumId, subForumId, threadId);
        }
        //+
        public DateTime getThreadCTime(int forumId, int subForumId, int threadId)
        {
            return sql_init.getThreadCTime(forumId, subForumId, threadId);
        }
        //+
        public SortedDictionary<int, Post> getThreadPosts(int forumId, int subForumId, int threadId)
        {
            return sql_init.getThreadPosts(forumId, subForumId, threadId);
        }
        //+
        public User getThreadPublishUser(int forumId, int subForumId, int threadId)
        {
            return sql_init.getThreadPublishUser(forumId, subForumId, threadId);
        }

 /*-       public void setIdForPosts(int forumId, int subForumId, int threadId, int idForPosts)
        {
            if (dataBase.getForums().ContainsKey(forumId))
                dataBase.getForum(forumId).getSubForum(subForumId).getThread(threadId).setIdForPosts(idForPosts);
        }
        */
        ///////////////////////////////////////////     Posts     /////////////////////////////////////////////////////
        //+
        public int addPost(int forumId, int subForumId, int threadId, string title, string body, User user)
        {
            int postId = sql_init.getIdForPosts(forumId, subForumId, threadId) + 1;
                //update DataBase
            sql_init.addPost(postId, forumId, subForumId, threadId, title, body, user.getUserName());
            return postId;
        }
        //+
        public bool removePost(int forumId, int subForumId, int threadId, int postId)
        {
            return sql_init.removePost(forumId, subForumId, threadId, postId);
        }
        //+
        public Post getPost(int forumId, int subForumId, int threadId, int postId) {
            return sql_init.getPost(forumId, subForumId, threadId, postId);
        }
        //+
        public void setPostTitle(int forumId, int subForumId, int threadId, int postId, string title) 
        {
            sql_init.updatePostTitle(forumId, subForumId, threadId, postId, title);
        }
        //+
        public string getPostTitle(int forumId, int subForumId, int threadId, int postId)
        {
            return sql_init.getPostTitle(forumId, subForumId, threadId, postId);
        }
        //+
        public void setPostBody(int forumId, int subForumId, int threadId, int postId, string body) 
        {
            sql_init.updatePostBody(forumId, subForumId, threadId, postId, body);
        }
        //+
        public string getPostBody(int forumId, int subForumId, int threadId, int postId)
        {
            return sql_init.getPostBody(forumId, subForumId, threadId, postId);
        }
        //+
        public User getPostCreatorUser(int forumId, int subForumId, int threadId, int postId)
        {
            return sql_init.getPostCreatorUser(forumId, subForumId, threadId, postId);   
        }


        //////////////////////////////////////////        Users       ///////////////////////////////////////////////
        //+
        public User registerUser(int forumId, string uname, string name, string lastName, string password, string email)
        {
            User user = sql_init.registerUser(forumId, uname, name, lastName, password, email);
            return user; 
 
        }
        //+
        public User registerUser(int forumId, User user)
        {
            return sql_init.registerUser(forumId, user.getUserName(), user.getName(), user.getLastName(), user.getPassword(), user.getEmail());
        }
        //+
        public bool containsUser(int forumId, string uname)
        {
            return sql_init.isForumUser(forumId, uname);
        }
        //+
        public bool isForumUser(int forumId, User user)
        {
            return sql_init.isForumUser(forumId, user.getUserName());
        }
        //+
        public bool isSubForumModerator(int forumId, int subForumId, User user) {
            return sql_init.isSubForumModerator(forumId, subForumId, user.getUserName());
        }
        //+
        public bool isSubForumModerator(int forumId, int subForumId, string user)
        {
            return sql_init.isSubForumModerator(forumId, subForumId, user);
        }
        //+
        public User getUser(int forumId, string uname)
        {
            return sql_init.getUser(uname, forumId);  
        }

        //+ Check if user is a member (for login).
        public bool isMember(int forumId, string username, string password)
        {
            return sql_init.isMember(forumId, username, password);
        }
        //+
        public string getLastName(int forumId, string username) 
        {
            return sql_init.getLastName(forumId, username);
        }
        //+
        public string getEmail(int forumId, string username)
        {
            return sql_init.getEmail(forumId, username);
        }

        //+ Return the user's friends. 
        public SortedDictionary<string, User> getFriends(int forumId, string username)
        {
            return sql_init.getFriends(forumId, username);
        }
        //+
        public bool addFriend(int forumId, string username, string friend)
        {    
         return sql_init.addFriend(forumId, username, friend);
        }
        //+
        public bool removeFriend(int forumId, string username, string friend)
        {
            return sql_init.removeFriend(forumId, username, friend);
        }
        //+
        public int getModeratorComplaints(int forumId, int subForumId, User moderator)
        {
            return sql_init.getModeratorComplaints(forumId, subForumId, moderator.getUserName());
        }
        //+
        public int getModeratorComplaints(int forumId, int subForumId, string moderator) {
            return sql_init.getModeratorComplaints(forumId, subForumId, moderator);
        }

        //+ remove moderator in sub forum. Return true in success, otherwise false.
        public bool removeModerator(int forumId, int subForumId, string m_name)
        {
         return sql_init.removeModerator(forumId, subForumId, m_name);
        }
        //+
        public void setModeratorComplaints(int forumId, int subForumId, string moderator, int complaint)
        {
            sql_init.updateModeratorComplaints(forumId, subForumId, moderator, complaint);
        }
        //+
        public bool containsMail(int forumId, string email){
            return sql_init.containsMail(forumId, email);
        }
        //+
        public bool containForbiddenWord(int forumId, string word) {
            return sql_init.containForbiddenWord(forumId, word);
        }
        //+
        public void addForbiddenWord(int forumId, string word)
        {
            sql_init.addForbiddenWord(forumId, word);
        }
        //+
        public SortedDictionary<string, string> getForbiddenWords(int forumId) {
            return sql_init.getForbiddenWords(forumId);
        }

      ////////////////////              Permissions         ///////////////////////////////

       //only director has permission to add new forum (add new forum)
        public bool addForumPermission(User user) {
            return user.getUserName().Equals("Gilad");
        }
        //only director and admin of the forum have permission to change forum (set title)
        public bool changeForumPermission(int forumId, User user) {
            return (user.getUserName().Equals("Gilad") || user.getUserName().Equals(getForumAdmin(forumId).getUserName()));
        }

        //only director and admin of the forum have permission to change subforum (add and remove subforum, change title, remove moderator, add moderator)
        public bool changeSubForumPermission(int forumId, User user) {
            return (user.getUserName().Equals("Gilad") || user.getUserName().Equals(getForumAdmin(forumId).getUserName()));
        }

        //only director, admin , moderator or publish user of the subforum have permission to change thread (add and remove thread, change title and body,  )
        public bool changeThreadPermission(int forumId, int subforumId, int threadId, User user)
        {
            return (user.getUserName().Equals("Gilad")
                || user.getUserName().Equals(getForumAdmin(forumId).getUserName())
                || isSubForumModerator(forumId, subforumId, user.getUserName())
                || user.getUserName().Equals( getThreadPublishUser(forumId, subforumId, threadId)));
        }

      //all regestred users have permission to publish thread 
       public bool addThreadPermission(int forumId, User user) {
           //return dataBase.getForum(forumId).containsUser(user);
           return isForumUser(forumId, user);
        }

       //only director, admin , moderator (in subforum) or publish user of the post have permission to change post (add and remove post, change title and body,  )
       public bool changePostPermission(int forumId, int subforumId, int threadId, int postId, User user)
       {
           return (user.getUserName().Equals("Gilad")
               || user.getUserName().Equals(getForumAdmin(forumId).getUserName())
               || isSubForumModerator(forumId, subforumId, user.getUserName())
               || user.getUserName().Equals(getPostCreatorUser(forumId, subforumId, threadId, postId)));
       }

       //all regestred users have permission to publish post
       public bool addPostPermission(int forumId, User user)
       {
           return isForumUser(forumId, user);
       }

    }
}
